import { AnimationClip, Sprite, SpriteFrame, animation } from "cc";
import { StateMachine } from "./StateMachine";
import { EntityTypeEnum, StateTypeEnum } from "../Common";
import ResourcesManager from "../Runtime/ResourcesManager";

export class State {

    clip: AnimationClip
    constructor(
        private fsm: StateMachine,
        private entityType: EntityTypeEnum,
        private type: StateTypeEnum,
        private wrapMode: AnimationClip.WrapMode = AnimationClip.WrapMode.Loop,
        private speed = 10
    ) {

        const track = new animation.ObjectTrack()
        track.path = new animation.TrackPath().toHierarchy('body').toComponent(Sprite).toProperty('spriteFrame')
        const spriteFrames = ResourcesManager.Ins.textureMap.get(this.entityType)

        const frames = spriteFrames ? this.getSpriteFrames(spriteFrames) : []

        track.channel.curve.assignSorted(frames)

        this.clip = new AnimationClip()
        this.clip.name = this.type.toString()
        this.clip.duration = frames.length
        this.clip.wrapMode = this.wrapMode
        this.clip.addTrack(track)
        this.clip.speed = this.speed

    }

    run() {
        if (
            this.fsm.animationComponent?.defaultClip?.name == this.type.toString()
            && this.type !== StateTypeEnum.shoot
        ) {
            return
        }
        this.fsm.animationComponent.defaultClip = this.clip
        this.fsm.animationComponent.play()

    }

    /** 获取帧动画图 */
    getSpriteFrames(spriteFrames: SpriteFrame[]) {

        let index = 0
        let frames: [number, SpriteFrame][] = []
    
        if (
            this.entityType === EntityTypeEnum.explosion ||
            this.entityType === EntityTypeEnum.gunFire ||
            this.entityType === EntityTypeEnum.bullet1 ||
            this.entityType === EntityTypeEnum.bullet2 ||
            this.entityType === EntityTypeEnum.bullet3
        ) {
            spriteFrames.map((v, i) => {
                frames.push([index++, v])
            })
        } else {
            spriteFrames.map((v, i) => {
                if (this.type === StateTypeEnum.none && v.name.includes('idle')) {
                    frames.push([index++, v])
                } else if (this.type === StateTypeEnum.run && v.name.includes('run')) {
                    frames.push([index++, v])
                } else if (this.type === StateTypeEnum.idle && v.name.includes('idle')) {
                    frames.push([index++, v])
                }
            })
        }

        return frames
    }
}